package com.baizhi.advice;

import com.alibaba.fastjson.JSONObject;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.DigestUtils;
import redis.clients.jedis.Jedis;

@Configuration
@Aspect
public class RedisCacheAdvice {

    @Around("@annotation(com.baizhi.annotations.RedisCache)")
    public Object around(ProceedingJoinPoint pjp){
        //获取Hashkey
        Jedis jedis = new Jedis("192.168.93.136", 7000);
        String key = getHashKey(pjp);
        Object result = null;
        if(jedis.hexists(key, getHashValueKey(pjp))){
            System.out.println("我调用的是缓存!!");
            String json = jedis.hget(getHashKey(pjp), getHashValueKey(pjp));
            MethodSignature signature = (MethodSignature) pjp.getSignature();
             result = JSONObject.parseObject(json, signature.getMethod().getGenericReturnType());
        }else{
            System.out.println("我调用的是数据库");
            //放行 并且存入缓存
            try {
                 result = pjp.proceed();
                 jedis.hset(getHashKey(pjp), getHashValueKey(pjp), JSONObject.toJSONString(result));
            } catch (Throwable throwable) {
                throwable.printStackTrace();
            }
        }
        return result;
    }

        //维护增删改
        @After("execution(* com.baizhi.service.*ServiceImpl.*(..)) && !@annotation(com.baizhi.annotations.RedisCache)")
        public void after(JoinPoint point){
            //获取keyPrefix
            String keyPrefix = DigestUtils.md5DigestAsHex(point.getTarget().getClass().getName().getBytes());
            Jedis jedis = new Jedis("192.168.93.136", 7000);
            jedis.del(keyPrefix);
        }

    //生成hashkey
    public String getHashKey(ProceedingJoinPoint pjp){
        //得到类名
        String className = pjp.getTarget().getClass().getName();
        String keyPrefix = DigestUtils.md5DigestAsHex(className.getBytes());
        return keyPrefix;
    }

    //生成hash中 value的key
    public String getHashValueKey(ProceedingJoinPoint pjp){
        StringBuilder builder = new StringBuilder();
        //获取方法名
        String name = pjp.getSignature().getName();
        builder.append(name);
        //获取参数
        for (Object arg :pjp.getArgs() ) {
            builder.append(arg);
        }
        String keySuffix = DigestUtils.md5DigestAsHex(builder.toString().getBytes());
        return keySuffix;
    }













    public String getKey(ProceedingJoinPoint pjp){
        StringBuilder builder = new StringBuilder();
        builder.append(pjp.getTarget().getClass().getName()).append(pjp.getSignature().getName());
        //参数
        for (Object arg :pjp.getArgs() ) {
            builder.append(arg);
        }
        System.out.println(builder.toString());
        return DigestUtils.md5DigestAsHex(builder.toString().getBytes());
    }
}
